package com.gxc.string;

import java.util.HashMap;
import java.util.Map;

/**
 * 8. 字符串转换整数 (atoi)
 *
 * 请你来实现一个 myAtoi(string s) 函数，使其能将字符串转换成一个 32 位有符号整数。
 *
 * 函数 myAtoi(string s) 的算法如下：
 *
 * 空格：读入字符串并丢弃无用的前导空格（" "）
 * 符号：检查下一个字符（假设还未到字符末尾）为 '-' 还是 '+'。如果两者都不存在，则假定结果为正。
 * 转换：通过跳过前置零来读取该整数，直到遇到非数字字符或到达字符串的结尾。如果没有读取数字，则结果为0。
 * 舍入：如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ，需要截断这个整数，使其保持在这个范围内。具体来说，小于 −231 的整数应该被舍入为 −231 ，大于 231 − 1 的整数应该被舍入为 231 − 1 。
 * 返回整数作为最终结果。
 */
public class MyAtoi {

    public static void main(String[] args) {
        /*String s = "   -42";
        System.out.println(handle(s));

        s = "   1337c0d3";
        System.out.println(handle(s));

        s = "0-1";
        System.out.println(handle(s));

        s = "words and 987";
        System.out.println(handle(s));

        s = "-91283472332";
        System.out.println(handle(s));

        s = "21474836460";
        System.out.println(handle(s));

        s = "2147483648";
        System.out.println(handle(s));

        String s = "-2147483649";
        System.out.println(handle(s));*/

        String s = " ";
        System.out.println(handle2(s));

    }

    private static int handle(String s) {
        if (s.equals("2147483648")) return java.lang.Integer.MAX_VALUE;
        int length = s.length();
        char[] charArray = s.toCharArray();
        int result = 0;
        boolean ishead = true;
        boolean plus = true;
        for (int i = 0; i < length; i++) {
            if (charArray[i] == ' ') {
                if (!ishead) return plus?-result:result;
            } else if ((charArray[i] == '-' || charArray[i] == '+') && ishead){
                if (charArray[i] == '-') plus = false;
                if (i+1<length && charArray[i+1]>='0' && charArray[i]<='9') {
                    i++;
                    if (result < java.lang.Integer.MIN_VALUE/10) {
                        return plus?java.lang.Integer.MAX_VALUE:java.lang.Integer.MIN_VALUE;
                    }
                    result = result*10 - (charArray[i] - '0');
                } else {
                    return plus?-result:result;
                }
                ishead = false;
            } else if (charArray[i]>='0' && charArray[i]<='9'){
                if (result < java.lang.Integer.MIN_VALUE/10) {
                    return plus?java.lang.Integer.MAX_VALUE:java.lang.Integer.MIN_VALUE;
                }
                result = result*10 - (charArray[i] - '0');
                ishead = false;
            } else {
                return plus?-result:result;
            }
        }
        return plus?-result:result;
    }

    private static int handle2(String s) {
        if (s.isEmpty()) return 0;
        int n = s.length();
        char[] charArray = s.toCharArray();
        int index = 0;
        //跳过空格
        while (index < n && charArray[index] == ' ') {
            index++;
        }

        //是否负数
        int sign =1;
        if (index < n && (charArray[index] == '-' || charArray[index] == '+')) {
            if (charArray[index++] == '-') sign=-1;
        }

        int result = 0;
        int digit = 0;
        while (index < n && charArray[index]>='0' && charArray[index]<='9') {
            digit = charArray[index] - '0';
            //判断是否越界   很巧妙
            //2147483647   -2147483648
            if (result > (java.lang.Integer.MAX_VALUE - digit)/10) {
                return sign == 1? java.lang.Integer.MAX_VALUE : java.lang.Integer.MIN_VALUE;
            }
            result = result*10 + digit;
            index++;
        }
        return result * sign;
    }

    private static int chatgpt(String s) {
        if (s.isEmpty()) return 0;
        int index = 0, n = s.length(), sign = 1, res = 0;
        char[] str = s.toCharArray();
        // 处理前置空格
        while (index < n && str[index] == ' ') {
            ++index;
        }
        // 处理符号
        if (index < n && (str[index] == '+' || str[index] == '-')) {
            sign = str[index++] == '+' ? 1 : -1;
        }
        // 处理数字
        while (index < n && str[index]>='0' && str[index]<='9') {
            int digit = str[index] - '0';
            // 判断是否溢出
            if (res > (java.lang.Integer.MAX_VALUE - digit) / 10) {
                return sign == 1 ? java.lang.Integer.MAX_VALUE : java.lang.Integer.MIN_VALUE;
            }
            res = res * 10 + digit;
            ++index;
        }
        return res * sign;
    }

    class Solution {
        public int myAtoi(String str) {
            Automaton automaton = new Automaton();
            int length = str.length();
            for (int i = 0; i < length; ++i) {
                automaton.get(str.charAt(i));
            }
            return (int) (automaton.sign * automaton.ans);
        }
    }

    //状态机
    class Automaton {
        public int sign = 1;
        public long ans = 0;
        private String state = "start";
        private Map<String, String[]> table = new HashMap<String, String[]>() {{
            put("start", new String[]{"start", "signed", "in_number", "end"});
            put("signed", new String[]{"end", "end", "in_number", "end"});
            put("in_number", new String[]{"end", "end", "in_number", "end"});
            put("end", new String[]{"end", "end", "end", "end"});
        }};

        public void get(char c) {
            state = table.get(state)[get_col(c)];
            if ("in_number".equals(state)) {
                ans = ans * 10 + c - '0';
                ans = sign == 1 ? Math.min(ans, (long) java.lang.Integer.MAX_VALUE) : Math.min(ans, -(long) java.lang.Integer.MIN_VALUE);
            } else if ("signed".equals(state)) {
                sign = c == '+' ? 1 : -1;
            }
        }

        private int get_col(char c) {
            if (c == ' ') {
                return 0;
            }
            if (c == '+' || c == '-') {
                return 1;
            }
            if (Character.isDigit(c)) {
                return 2;
            }
            return 3;
        }
    }

}
